package com.yupi.springbootinit.service.workflow;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yupi.springbootinit.mapper.WorkflowTaskMapper;
import com.yupi.springbootinit.model.entity.User;
import com.yupi.springbootinit.model.entity.WorkflowTask;
import com.yupi.springbootinit.model.vo.WorkflowTaskVO;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import static com.yupi.springbootinit.service.workflow.WorkflowTaskConstants.*;

/**
 * 工作流任务查询服务
 */
@Slf4j
@Service
public class WorkflowTaskQueryService {

    @Resource
    private WorkflowTaskMapper workflowTaskMapper;

    @Resource
    private WorkflowTaskUtils workflowTaskUtils;

    @Resource
    private WorkflowTaskPermissionService permissionService;

    /**
     * 分页查询部门任务（原始实体）
     */
    public Page<WorkflowTask> pageDepartmentTasks(Long departmentId, String status, long current, long size) {
        if (departmentId == null) {
            return new Page<>(current, size, 0);
        }
        
        QueryWrapper<WorkflowTask> qw = new QueryWrapper<>();
        qw.eq("departmentId", departmentId)
          .ne("taskType", TASK_TYPE_PUBLISH_BATCH) // 部门任务列表中排除子任务
          .eq("isDelete", 0);
          
        if (StringUtils.isNotBlank(status)) {
            qw.eq("taskStatus", status);
        }
        
        // 按业务优先级排序：待处理 → 进行中 → 已完成，每个状态内按时间倒序
        qw.last("ORDER BY CASE taskStatus " +
                "WHEN 'PENDING' THEN 1 " +
                "WHEN 'IN_PROGRESS' THEN 2 " +
                "WHEN 'DONE' THEN 3 " +
                "ELSE 4 END ASC, createTime DESC");

        return workflowTaskMapper.selectPage(new Page<>(current, size), qw);
    }

    /**
     * 分页查询部门任务（VO）
     */
    public Page<WorkflowTaskVO> pageDepartmentTasksVO(Long departmentId, String status, long current, long size, User currentUser) {
        if (departmentId == null) {
            return new Page<>(current, size, 0);
        }
        
        QueryWrapper<WorkflowTask> qw = new QueryWrapper<>();
        qw.eq("departmentId", departmentId)
          .ne("taskType", TASK_TYPE_PUBLISH_BATCH) // 部门任务列表中排除子任务
          .eq("isDelete", 0);
          
        if (StringUtils.isNotBlank(status)) {
            qw.eq("taskStatus", status);
        }
        
        // 按业务优先级排序：待处理 → 进行中 → 已完成，每个状态内按时间倒序
        qw.last("ORDER BY CASE taskStatus " +
                "WHEN 'PENDING' THEN 1 " +
                "WHEN 'IN_PROGRESS' THEN 2 " +
                "WHEN 'DONE' THEN 3 " +
                "ELSE 4 END ASC, createTime DESC");
                
        Page<WorkflowTask> page = workflowTaskMapper.selectPage(new Page<>(current, size), qw);
        
        // 转换为VO并计算权限
        Page<WorkflowTaskVO> voPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
        List<WorkflowTaskVO> voList = page.getRecords().stream()
                .map(task -> convertToVOWithPermissions(task, currentUser))
                .collect(Collectors.toList());
        voPage.setRecords(voList);
        return voPage;
    }

    /**
     * 分页查询个人任务
     */
    public Page<WorkflowTaskVO> pageMyTasks(Long userId, String status, long current, long size, User currentUser) {
        if (userId == null) {
            return new Page<>(current, size, 0);
        }

        QueryWrapper<WorkflowTask> qw = new QueryWrapper<>();
        qw.eq("claimedBy", userId).isNull("parentTaskId")  // ✅ 修改：只查询顶层任务（父任务）
                .eq("isDelete", 0);

        if (StringUtils.isNotBlank(status)) {
            qw.eq("taskStatus", status);
        }

        // 按业务优先级排序：待处理 → 进行中 → 已完成，每个状态内按时间倒序
        qw.last("ORDER BY CASE taskStatus " +
                "WHEN 'PENDING' THEN 1 " +
                "WHEN 'IN_PROGRESS' THEN 2 " +
                "WHEN 'DONE' THEN 3 " +
                "ELSE 4 END ASC, createTime DESC");

        Page<WorkflowTask> page = workflowTaskMapper.selectPage(new Page<>(current, size), qw);

        // 转换为VO并计算权限
        Page<WorkflowTaskVO> voPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
        List<WorkflowTaskVO> voList = page.getRecords().stream()
                .map(task -> convertToVOWithPermissions(task, currentUser))
                .collect(Collectors.toList());
        voPage.setRecords(voList);
        return voPage;
    }

    /**
     * 查询叶子节点任务（顶部栏待办）
     */
    public Page<WorkflowTaskVO> pageMyLeafTasks(Long userId, String status, long current, long size, User currentUser) {
        if (userId == null) {
            return new Page<>(current, size, 0);
        }

        // 1. 查询所有任务
        QueryWrapper<WorkflowTask> allQw = new QueryWrapper<>();
        allQw.eq("claimedBy", userId).eq("isDelete", 0);
        if (StringUtils.isNotBlank(status)) {
            allQw.eq("taskStatus", status);
        }
        List<WorkflowTask> allTasks = workflowTaskMapper.selectList(allQw);

        // 2. 找出所有有子任务的父任务ID
        Set<Long> parentIdsWithChildren = allTasks.stream().filter(t -> t.getParentTaskId() != null).map(WorkflowTask::getParentTaskId).collect(Collectors.toSet());

        // 3. 过滤出叶子节点任务（无子任务的父任务 + 所有子任务）
        List<WorkflowTask> leafTasks = allTasks.stream().filter(t -> {
            // 如果是父任务且有子任务，则不包含
            if (t.getParentTaskId() == null && parentIdsWithChildren.contains(t.getId())) {
                return false;
            }
            return true;
        }).sorted((t1, t2) -> {
            // 排序：PENDING > IN_PROGRESS > DONE，相同状态按时间倒序
            int status1 = getStatusOrder(t1.getTaskStatus());
            int status2 = getStatusOrder(t2.getTaskStatus());
            if (status1 != status2) {
                return Integer.compare(status1, status2);
            }
            return t2.getCreateTime().compareTo(t1.getCreateTime());
        }).collect(Collectors.toList());

        // 4. 手动分页
        int fromIndex = (int) ((current - 1) * size);
        int toIndex = Math.min(fromIndex + (int) size, leafTasks.size());
        List<WorkflowTask> pagedLeafTasks = leafTasks.subList(Math.min(fromIndex, leafTasks.size()), toIndex);

        // 5. 转换为VO
        Page<WorkflowTaskVO> voPage = new Page<>(current, size, leafTasks.size());
        List<WorkflowTaskVO> voList = pagedLeafTasks.stream().map(task -> convertToVOWithPermissions(task, currentUser)).collect(Collectors.toList());
        voPage.setRecords(voList);

        return voPage;
    }

    private int getStatusOrder(String status) {
        switch (status) {
            case "PENDING":
                return 1;
            case "IN_PROGRESS":
                return 2;
            case "DONE":
            case "COMPLETED":
                return 3;
            default:
                return 4;
        }
    }
    /**
     * 分页查询个人工艺单任务
     */
    public Page<WorkflowTaskVO> pageMyProcessSheetTasks(Long userId, String status, long current, long size, User currentUser) {
        if (userId == null) {
            return new Page<>(current, size, 0);
        }
        
        QueryWrapper<WorkflowTask> qw = new QueryWrapper<>();
        qw.eq("claimedBy", userId)
          .eq("taskType", TASK_TYPE_CREATE_PROCESS_SHEET)
          .eq("isDelete", 0);
          
        if (StringUtils.isNotBlank(status)) {
            qw.eq("taskStatus", status);
        }
        
        // 按业务优先级排序：待处理 → 进行中 → 已完成，每个状态内按时间倒序
        qw.last("ORDER BY CASE taskStatus " +
                "WHEN 'PENDING' THEN 1 " +
                "WHEN 'IN_PROGRESS' THEN 2 " +
                "WHEN 'DONE' THEN 3 " +
                "ELSE 4 END ASC, createTime DESC");
                
        Page<WorkflowTask> page = workflowTaskMapper.selectPage(new Page<>(current, size), qw);
        
        // 转换为VO并计算权限
        Page<WorkflowTaskVO> voPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
        List<WorkflowTaskVO> voList = page.getRecords().stream()
                .map(task -> convertToVOWithPermissions(task, currentUser))
                .collect(Collectors.toList());
        voPage.setRecords(voList);
        return voPage;
    }

    /**
     * 分页查询工艺单任务
     */
    public Page<WorkflowTaskVO> pageProcessSheetTasks(Long userId, boolean isAdmin, String status, long current, long size, User currentUser) {
        QueryWrapper<WorkflowTask> qw = new QueryWrapper<>();
        qw.eq("taskType", TASK_TYPE_CREATE_PROCESS_SHEET)
          .eq("isDelete", 0);
        
        // 非管理员只能查看自己认领的任务
        if (!isAdmin) {
            if (userId == null) {
                return new Page<>(current, size, 0);
            }
            qw.eq("claimedBy", userId);
        }
        // 管理员可以查看所有任务，也可以指定查看某个用户的任务
        else if (userId != null) {
            qw.eq("claimedBy", userId);
        }
        
        if (StringUtils.isNotBlank(status)) {
            qw.eq("taskStatus", status);
        }
        
        // 按业务优先级排序：待处理 → 进行中 → 已完成，每个状态内按时间倒序
        qw.last("ORDER BY CASE taskStatus " +
                "WHEN 'PENDING' THEN 1 " +
                "WHEN 'IN_PROGRESS' THEN 2 " +
                "WHEN 'DONE' THEN 3 " +
                "ELSE 4 END ASC, createTime DESC");
                
        Page<WorkflowTask> page = workflowTaskMapper.selectPage(new Page<>(current, size), qw);
        
        // 转换为VO并计算权限
        Page<WorkflowTaskVO> voPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
        List<WorkflowTaskVO> voList = page.getRecords().stream()
                .map(task -> convertToVOWithPermissions(task, currentUser))
                .collect(Collectors.toList());
        voPage.setRecords(voList);
        return voPage;
    }

    /**
     * 转换为VO（基础字段）
     */
    private WorkflowTaskVO convertToVO(WorkflowTask task) {
        WorkflowTaskVO vo = new WorkflowTaskVO();
        BeanUtils.copyProperties(task, vo);

        // ✅ 手动设置 parentTaskId（Long -> String，避免前端精度丢失）
        if (task.getParentTaskId() != null) {
            vo.setParentTaskId(String.valueOf(task.getParentTaskId()));
        }

        // 设置状态显示名称
        vo.setTaskStatusName(workflowTaskUtils.getStatusDisplayName(task.getTaskStatus()));
        vo.setPriorityName(workflowTaskUtils.getPriorityDisplayName(task.getPriority()));

        // 设置认领状态
        vo.setIsClaimed(task.getClaimedBy() != null);
        // ✅ 关键修复：PUBLISH_BATCH类型任务不允许认领
        boolean isPendingAndUnclaimed = STATUS_PENDING.equals(task.getTaskStatus()) && task.getClaimedBy() == null;
        boolean isPublishBatch = TASK_TYPE_PUBLISH_BATCH.equals(task.getTaskType());
        vo.setCanClaim(isPendingAndUnclaimed && !isPublishBatch);

        // 设置逾期状态
        vo.setIsOverdue(workflowTaskUtils.isTaskOverdue(task));

        return vo;
    }

    /**
     * 转换为VO并计算权限信息
     * 
     * @param task 任务实体
     * @param currentUser 当前用户
     * @return 带有权限信息的VO
     */
    private WorkflowTaskVO convertToVOWithPermissions(WorkflowTask task, User currentUser) {
        WorkflowTaskVO vo = convertToVO(task);
        
        // 计算并填充权限信息
        if (currentUser != null) {
            permissionService.calculateTaskPermissions(vo, currentUser);
        }
        
        return vo;
    }

    /**
     * 查询父任务下的所有子任务
     * 
     * @param parentTaskId 父任务ID
     * @param currentUser 当前用户
     * @return 子任务列表
     */
    public List<WorkflowTaskVO> listSubTasks(Long parentTaskId, User currentUser) {
        if (parentTaskId == null) {
            return Collections.emptyList();
        }
        
        QueryWrapper<WorkflowTask> qw = new QueryWrapper<>();
        qw.eq("parentTaskId", parentTaskId)
          .eq("isDelete", 0)
          .orderByAsc("createTime"); // 按创建时间排序
        
        List<WorkflowTask> tasks = workflowTaskMapper.selectList(qw);
        if (tasks == null || tasks.isEmpty()) {
            return Collections.emptyList();
        }
        
        // 转换为VO并计算权限
        List<WorkflowTaskVO> voList = tasks.stream()
                .map(task -> convertToVOWithPermissions(task, currentUser))
                .collect(Collectors.toList());
        
        log.info("查询子任务: parentTaskId={}, count={}", parentTaskId, voList.size());
        return voList;
    }
}